`timescale 1ns/1ps
module moore_machine_top;
    reg clk,rst;
    reg [1:0]X;
    wire [3:0]Z;
    always # 1 clk= ~clk;
    initial begin
        clk = 0;
        rst = 0;
        X = 2'b00;
        # 2 rst= 1 ;
        # 4 rst= 0 ;
        # 2 X = 2'b01;
        # 2 X = 2'b01;
        # 2 X = 2'b10;
        # 2 X = 2'b11;
        # 2 X = 2'b00;
        # 4 X = 2'b01;
        # 4 X = 2'b00;
        # 2 X = 2'b10;
        # 2 X = 2'b11;

        # 10 X = 2'b10;
        # 4 rst = 1; 
        # 2 $stop;
    end
    moore_machine mm(Z,X,clk,rst);
	initial
	begin
    	$dumpfile("test.vcd");
    	$dumpvars(0, mm);
 	end
endmodule

module moore_machine(Z,X,clk,rst);
	input clk,rst;
    input [1:0] X;
    output [3:0]Z;
    reg [2:0]state,next;
    parameter RST = 3'b000, S0 = 3'b001 ,S1 = 3'b010;
    parameter S2 = 3'b011,S3 = 3'b100;
    
    assign Z = (state ==S3)?4'd14: 
        (state == S2)?4'd12:
        (state == S1)?4'd8:
        (state == S0)?4'd5:4'd0;
    
    always @(posedge clk or posedge rst)
        if(rst)
            state <= RST;
    	else
            state <= next;
    
    always @(*)
        case(state)
            RST:next = S0;
            S0:next = (X==2'b00)?S0:S1;
            S1:next = (X==2'b00)?S1:S2;
            S2:next = (X==2'b11)?S0:S3;
            S3:next = (X==2'b11)?S3:S0;
            default:next = RST;
        endcase
endmodule
